#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")
#define High 600
#define Width 350

// 全局变量
IMAGE img_bk,img_bd1,img_bd2,img_bar_up1,img_bar_up2,img_bar_up3,img_bar_up4,img_bar_down1,img_bar_down2,img_bar_down3,img_bar_down4,score1[10],score2[10];
IMAGE img_gameover1,img_gameover2; // 游戏结束
int bird_x,bird_y,i=0,k=0; // 小鸟坐标
int bar_x1,bar_y1;// 上截柱子左下坐标
int bar_x2,bar_y2;// 下截柱子左下坐标
int score;
MOUSEMSG m; // 定义鼠标消息

void startup() // 初始化数据
{
	mciSendString("open \"D:\\Flappy Bird\\background.mp3\" alias music ", NULL, 0, NULL);//背景音乐
	mciSendString("play music", NULL, 0, NULL);  // 循环播放

	initgraph(Width,High); // 画面大小
	loadimage(&img_bk, "D:\\Flappy Bird\\background.png"); // 背景图片
	BeginBatchDraw(); // 开始批量绘图
	// 鸟
	loadimage(&img_bd1, "D:\\Flappy Bird\\bird1.jpg");
	loadimage(&img_bd2, "D:\\Flappy Bird\\bird2.jpg");
	// 柱子
	loadimage(&img_bar_up1, "D:\\Flappy Bird\\bar_up1.gif");
	loadimage(&img_bar_up2, "D:\\Flappy Bird\\bar_up2.gif");
	loadimage(&img_bar_down1, "D:\\Flappy Bird\\bar_down1.gif");
	loadimage(&img_bar_down2, "D:\\Flappy Bird\\bar_down2.gif");
	loadimage(&img_bar_up3, "D:\\Flappy Bird\\bar_up1.gif");
	loadimage(&img_bar_up4, "D:\\Flappy Bird\\bar_up2.gif");
	loadimage(&img_bar_down3, "D:\\Flappy Bird\\bar_down1.gif");
	loadimage(&img_bar_down4, "D:\\Flappy Bird\\bar_down2.gif");
	// 得分
	loadimage(&score1[0],"D:\\Flappy Bird\\0_1.jpg");
	loadimage(&score2[0],"D:\\Flappy Bird\\0_2.jpg");
	loadimage(&score1[1],"D:\\Flappy Bird\\1_1.jpg");
	loadimage(&score2[1],"D:\\Flappy Bird\\1_2.jpg");
	loadimage(&score1[2],"D:\\Flappy Bird\\2_1.jpg");
	loadimage(&score2[2],"D:\\Flappy Bird\\2_2.jpg");
	loadimage(&score1[3],"D:\\Flappy Bird\\3_1.jpg");
	loadimage(&score2[3],"D:\\Flappy Bird\\3_2.jpg");
	loadimage(&score1[4],"D:\\Flappy Bird\\4_1.jpg");
	loadimage(&score2[4],"D:\\Flappy Bird\\4_2.jpg");
	loadimage(&score1[5],"D:\\Flappy Bird\\5_1.jpg");
	loadimage(&score2[5],"D:\\Flappy Bird\\5_2.jpg");
	loadimage(&score1[6],"D:\\Flappy Bird\\6_1.jpg");
	loadimage(&score2[6],"D:\\Flappy Bird\\6_2.jpg");
	loadimage(&score1[7],"D:\\Flappy Bird\\7_1.jpg");
	loadimage(&score2[7],"D:\\Flappy Bird\\7_2.jpg");
	loadimage(&score1[8],"D:\\Flappy Bird\\8_1.jpg");
	loadimage(&score2[8],"D:\\Flappy Bird\\8_2.jpg");
	loadimage(&score1[9],"D:\\Flappy Bird\\9_1.jpg");
	loadimage(&score2[9],"D:\\Flappy Bird\\9_2.jpg");
	// 游戏结束
	loadimage(&img_gameover1,"D:\\Flappy Bird\\gameover1.gif");
	loadimage(&img_gameover2,"D:\\Flappy Bird\\gameover2.gif");

	bird_x = 150; // 鸟初始坐标
	bird_y = 300;
	// 消除第一根随机数bug柱子以及输出画面中第一根正常柱子
	bar_y1=rand()%310-555;
	bar_x1=350;
	bar_x2=bar_y2=-9999;
	// 得分初始化为0
	score = 0;
}

void printBar() // 画柱子
{
	Sleep(30);
	if(bar_x1>210) // 画面同时存在两根柱子
	{
		putimage(bar_x1, bar_y1, &img_bar_up1,NOTSRCERASE);
		putimage(bar_x1, bar_y1, &img_bar_up2,SRCINVERT);
		putimage(bar_x1, bar_y1+750, &img_bar_down1,NOTSRCERASE);
		putimage(bar_x1, bar_y1+750, &img_bar_down2,SRCINVERT);
		putimage(bar_x2, bar_y2, &img_bar_up3,NOTSRCERASE);
		putimage(bar_x2, bar_y2, &img_bar_up4,SRCINVERT);
		putimage(bar_x2, bar_y2+750, &img_bar_down3,NOTSRCERASE);
		putimage(bar_x2, bar_y2+750, &img_bar_down4,SRCINVERT);
		bar_x1--;bar_x2--;
	}
	else if(bar_x1==210)// 左柱子消失，将bar_x2,bar_y2值归位
	{
		bar_x2=bar_x1;
		bar_y2=bar_y1;
		putimage(bar_x1, bar_y1, &img_bar_up1,NOTSRCERASE);
		putimage(bar_x1, bar_y1, &img_bar_up2,SRCINVERT);
		putimage(bar_x1, bar_y1+750, &img_bar_down1,NOTSRCERASE);
		putimage(bar_x1, bar_y1+750, &img_bar_down2,SRCINVERT);
		bar_x1--;
		bar_x2--;
	}
	else if(bar_x1<210 && bar_x1>0)// 画面只存在一根柱子时
	{
		putimage(bar_x1, bar_y1, &img_bar_up1,NOTSRCERASE);
		putimage(bar_x1, bar_y1, &img_bar_up2,SRCINVERT);
		putimage(bar_x1, bar_y1+750, &img_bar_down1,NOTSRCERASE);
		putimage(bar_x1, bar_y1+750, &img_bar_down2,SRCINVERT);
		bar_x1--;
		bar_x2--;	 
	}
	if(bar_x1==0)// 柱子在左边消失，生成新柱子
	{	  
		bar_y1=rand()%310-555;
		bar_x1=350;
		putimage(bar_x1, bar_y1, &img_bar_up1,NOTSRCERASE);
		putimage(bar_x1, bar_y1, &img_bar_up2,SRCINVERT);
		putimage(bar_x1, bar_y1+750, &img_bar_down1,NOTSRCERASE);
		putimage(bar_x1, bar_y1+750, &img_bar_down2,SRCINVERT);
		bar_x1--;
		bar_x2--;
	}
}

void printScore() // 画得分
{
	IMAGE *mark1[6],*mark2[6];
	int sum,l_p=1,i=0,grade=score;
	if(grade==0)
	{
		putimage(250,50,&score1[0],NOTSRCERASE);
		putimage(250,50,&score2[0],SRCINVERT);
	}
	while(grade>0)
	{
		sum=grade%10;
		mark1[i]=&score1[sum];
		mark2[i]=&score2[sum]; 
		putimage(300-50*l_p,50,mark1[i],NOTSRCERASE);
		putimage(300-50*l_p,50,mark2[i],SRCINVERT);
		grade/=10;
		i++;
		l_p++;
	}
}

void show() // 显示游戏画面
{
	putimage(0,0, &img_bk); // 显示背景
	putimage(bird_x, bird_y,&img_bd1,NOTSRCERASE); // 画鸟
	putimage(bird_x, bird_y,&img_bd2,SRCINVERT);
	if(k%5==0)
		i++;
	k++;
	printBar(); // 画柱子
	printScore(); // 画得分
	FlushBatchDraw(); // 绘制
}

void updateWithoutInput() // 与输入无关的东西
{
	if(bird_y<580)
		bird_y = bird_y + 3; // 小鸟下落
}

void updateWithInput() // 就是控制叭
{
	char input;
	if(kbhit())
	{
		input = getch();
		if(input==' ' && bird_y>20)
		{
			bird_y = bird_y - 60;
			mciSendString("close jpmusic", NULL, 0, NULL); // 先把前面一次的音乐关闭
			mciSendString("open \"D:\\Flappy Bird\\Jump.mp3\" alias jpmusic", NULL, 0, NULL); // 打开跳动音乐
            mciSendString("play jpmusic", NULL, 0, NULL); // 仅播放一次
		}
	}
	while(MouseHit())
	{
		// 获取一条鼠标消息
		m = GetMouseMsg();
		switch(m.uMsg)
		{
		case WM_LBUTTONDOWN:
			bird_y-=60;
			break;
		case WM_RBUTTONDOWN:
			getch();
			break; // 右键暂停，按任意键盘继续
		}
	}
}

void gameover() // 游戏结束处理
{
	putimage(Width/2-96, High/2-20, &img_gameover1,NOTSRCERASE);
	putimage(Width/2-96, High/2-20, &img_gameover2,SRCINVERT);
	EndBatchDraw(); // 结束批量绘图
	getch();
	closegraph();
}

void Judgement()
{
	if((bar_x1>10 && bar_x1<20) || (bar_x1>174 && bar_x1<184))
	{
		if((bird_y>(bar_y1+576) && bird_y<(bar_y1+600))||((bird_y>(bar_y1+726)) && bird_y<(bar_y1+750)))
			gameover();//结束游戏
	}
	else if(bar_x1>=20 && bar_x1<=174)
	{
		if(!(bird_y>(bar_y1+600) && bird_y<(bar_y1+726)))
			gameover();	//结束游戏
	}
	if(bird_y>576)
		gameover();//结束游戏
	if(bar_x1==10)
		score++;
}

int main()
{
	startup(); // 数据初始化
	while(1)
	{
		show(); // 显示画面
		updateWithoutInput(); // 与用户输入无关的更新
		updateWithInput(); // 与用户输入有关的更新
		Judgement(); // 失败判定
	}
	return 0;
}